using Circus.CodeEditor;
using Circus.CodeEditor.CodeCompletion;
using Circus.CodeEditor.Serialization;
using Circus.CodeEditor.TextSource;
using Circus.Syntax;
using Circus.Syntax.CodeCompletion;
using Circus.Syntax.Lexer;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml.Serialization;


namespace Circus.CodeEditor {
    [ToolboxBitmap(typeof(CodeEditor), "Images.SyntaxEdit.bmp")]
    public partial class CodeEditor : Control, INotifier {
        private Container components = null;
        private OutlineRange mouseRange;
        private CodeSnippetRange snippetRange;
        private Point infoTipPos = new Point(-1, -1);
        private bool urlAtCursor;
        private string mouseUrl = string.Empty;
        private Point mouseUrlPoint;
        private Point mouseBookMarkPt;
        private bool dragMargin;
        private bool needStartDrag;
        private Point startDragPos;
        private Point saveDragPos;
        private char lastKey = '\0';
        private int keyState;
        private bool keyProcessed;
        private int lbuttonClicks;
        private Timer tripleClickTimer;
        private Circus.CodeEditor.TextSource.TextSource source;
        private Circus.CodeEditor.TextSource.TextSource innerTextSource;
        private Painter painter222;
        private KeyList keyList;
        private Gutter gutter;
        private Margin margin;
        private Selection2 selection;
        private WhiteSpace whiteSpace;
        private LineSeparator lineSeparator;
        private Braces braces;
        private EditHyperText hyperText;
        private Outlining outlining;
        private EditSpelling spelling;
        private Scrolling scrolling;
        private EditSyntaxPaint syntaxPaint;
        private EditLineStyles lineStyles;
        private DisplayStrings displayLines;
        private SyntaxError mouseError;
        private CodeEditor vertSplitEdit;
        private CodeEditor horzSplitEdit;
        private MacroKeyList macroRecords;
        private IBookMark mouseBookMark = null;
        private OutlineRange activeOutlineRange;
        private bool searchGlobal = false;
        private bool acceptReturns = true;
        private bool acceptTabs = true;
        private EditBorderStyle borderStyle = EditBorderStyle.Fixed3D;
        private Color borderColor = Color.Empty;
        private int lineSpace = 0;
        private bool transparent;
        private bool useDefaultMenu = true;
        private ContextMenuStrip defaultMenu;
        private ToolStripMenuItem miUndo;
        private ToolStripMenuItem miRedo;
        private ToolStripMenuItem miCut;
        private ToolStripMenuItem miCopy;
        private ToolStripMenuItem miPaste;
        private ToolStripMenuItem miDelete;
        private ToolStripMenuItem miSelectAll;
        private string searchText;
        private bool isReplace = false;
        private string replaceText;
        private SearchOptions searchOptions = EditConsts.DefaultSearchOptions;
        private Regex searchExpression;
        private Point searchPos;
        private Point searchStartPos;
        private bool searchCycled;
        private int searchLen;
        private Match searchMatch;
        private bool firstSearch = true;
        private bool inIncrementalSearch;
        private bool incrSearchFlag;
        private Point incrSearchPosition;
        private Point incrStartSearchPosition;
        private Cursor incrementalSearchCursor;
        private Cursor reverseIncrementalSearchCursor;
        private Rectangle searchSelRect;
        private SelectionType searchSelType;
        private int searchUpdateCount;
        private NotifyEventArgs notifyEventArgs;
   
        private bool highlightCurrentBlock;
        
        private Point oldDragPoint = new Point(-100, -100);
        private Range currentBlockRange;
        private int oldLine = -1;
        private int vertNavigateX;
        private bool vertNavigate;
        private CodeCompletionBox codeCompletionBox;
        private CodeCompletionHint codeCompletionHint;
        private char[] codeCompletionChars = EditConsts.DefaultCodeCompletionChars.ToCharArray();
        private Timer codeCompletionTimer;
        private CodeCompletionArgs codeCompletionArgs = new CodeCompletionArgs();
        private ThreadProc codeCompletionAction;
        private ThreadProc codeCompletionStart;
        private ThreadProc codeCompletionEnd;
        private bool macroRecording;
        private bool macroSuspended;
        private int macroUpdateCount;
        private Splitter vertSplitter;
        private Splitter horzSplitter;
        private char[] autoCorrectDelimiters = EditConsts.DefaultAutoCorrectDelimiters.ToCharArray();
        private bool autoCorrection = false;
        private AutoCorrectEventArgs autoCorrectEventArgs;
        [Category("SyntaxEdit"), Description("Occurs when selection bounds are changed.")]
        public event EventHandler SelectionChanged {
            add {
                this.selection.SelectionChanged += value;
            }
            remove {
                this.selection.SelectionChanged -= value;
            }
        }

        [Category("SyntaxEdit"), Description("Occurs when user attempts to jump to url.")]
        public event UrlJumpEvent JumpToUrl {
            add {
                this.hyperText.JumpToUrl += value;
            }
            remove {
                this.hyperText.JumpToUrl -= value;
            }
        }
        [Category("SyntaxEdit"), Description("Occurs when a control needs checking whether some string represents hypertext.")]
        public event HyperTextEvent CheckHyperText {
            add {
                this.hyperText.HyperText += value;
            }
            remove {
                this.hyperText.HyperText -= value;
            }
        }
        [Category("SyntaxEdit"), Description("Occurs when the gutter part of Edit control is clicked.")]
        public event EventHandler GutterClick {
            add {
                this.gutter.Click += value;
            }
            remove {
                this.gutter.Click -= value;
            }
        }
        [Category("SyntaxEdit"), Description("Occurs when the gutter part of Edit control is double-clicked.")]
        public event EventHandler GutterDblClick {
            add {
                this.gutter.DoubleClick += value;
            }
            remove {
                this.gutter.DoubleClick -= value;
            }
        }
      
        [Category("SyntaxEdit"), Description("Occurs when spelling of some word within the text needs checking.")]
        public event WordSpellEvent WordSpell {
            add {
                this.spelling.WordSpell += value;
            }
            remove {
                this.spelling.WordSpell -= value;
            }
        }
        [Category("SyntaxEdit"), Description("Occurs when control scrolls its content in vertical direction. This can be caused by dragging vertical scroll thumb, or caret moving.")]
        public event EventHandler VerticalScroll {
            add {
                this.scrolling.VerticalScroll += value;
            }
            remove {
                this.scrolling.VerticalScroll -= value;
            }
        }
        [Category("SyntaxEdit"), Description("Occurs when control scrolls its content in horizonal direction. This can be caused by dragging horizonal scroll thumb, or caret moving.")]
        public event EventHandler HorizontalScroll {
            add {
                this.scrolling.HorizontalScroll += value;
            }
            remove {
                this.scrolling.HorizontalScroll -= value;
            }
        }
      
        [Category("SyntaxEdit"), Description("Occurs when undo/redo operation performed.")]
        public event UndoEvent UndoEvent {
            add {
                this.Source.UndoEvent += value;
            }
            remove {
                this.Source.UndoEvent -= value;
            }
        }

        [Category("SyntaxEdit"), Description("Occurs when text Source's state is changed, for example when caret position moved, text edited, amount of lines changed, lexer changed, etc.")]
        public event NotifyEvent SourceStateChanged;

        [Category("SyntaxEdit"), Description("Occurs when modified state is changed.")]
        public event EventHandler ModifiedChanged;

        [Category("SyntaxEdit"), Description("Occurs when replace dialog prompts on replace action.")]
        public event PromptOnReplaceEvent PromptOnReplace;


        [Category("SyntaxEdit"), Description("Occurs when code completion window is to be displayed.")]
        public event CodeCompletionEvent NeedCodeCompletion;

        [Category("SyntaxEdit"), Description("Occurs when control tries to auto correct word being typed.")]
        public event AutoCorrectEvent AutoCorrect;
        [Description("Gets or sets the string collection as a single string with the individual lines delimited by carriage returns.")]
        public override string Text {
            get {
                return this.Lines.Text;
            }
            set {
                this.Lines.Text = value;
            }
        }
       
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public ContextMenuStrip DefaultMenu {
            get {
                if (this.defaultMenu == null) {
                    this.InitDefaultMenu();
                }
                return this.defaultMenu;
            }
            set {
                if (this.defaultMenu != value) {
                    this.defaultMenu = value;
                    this.OnDefaultMenuChanged();
                }
            }
        }
        protected bool IsTransparent {
            get {
                return this.transparent;
            }
        }
        protected override CreateParams CreateParams {
            get {
                CreateParams createParams = base.CreateParams;
                switch (this.borderStyle) {
                    case EditBorderStyle.Fixed3D:
                    case EditBorderStyle.System:
                        createParams.ExStyle |= 512;
                        break;
                    case EditBorderStyle.FixedSingle:
                        createParams.Style |= 8388608;
                        break;
                }
                return createParams;
            }
        }
        protected Cursor LeftArrowCursor {
            get {
                return Resources.leftArrow;
            }
        }
    
        [Category("SyntaxEdit"), Description("Gets or sets an object that implements \"ITextSource\" interface containing an actual string data displayed by the control.")]
        public virtual Circus.CodeEditor.TextSource.TextSource Source {
            get {
                return (this.source != null) ? this.source : this.innerTextSource;
            }
            set {
                if (this.source != value) {
                    if (this.source != null) {
                        this.source.RemoveNotifier(this);
                        this.source.ActiveEdit = null;
                    }
                    this.source = value;
                    if (this.source != null) {
                        this.source.AddNotifier(this);
                        if (this.source.ActiveEdit == null) {
                            this.source.ActiveEdit = this;
                        }
                    }
                    this.OnSourceChanged();
                }
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual TextStrings Lines {
            get {
                return this.Source.Lines;
            }
            set {
                this.Source.Lines = value;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual DisplayStrings DisplayLines {
            get {
                return this.displayLines;
            }
        }
        [Category("SyntaxEdit"), Description("Represents an object that implements \"ISelection\" interface. This object represents various properties and methods to manipulate text selection, such as copy, paste and drag selected text."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), TypeConverter(typeof(ExpandableObjectConverter))]
        public virtual Selection2 Selection {
            get {
                return this.selection;
            }
            set {
                if (this.selection != value) {
                    this.selection = value;
                    this.OnSelectionChanged();
                }
            }
        }
        [Category("SyntaxEdit"), Description("Represents object that implements \"IGutter\" interface containing methods and properties necessary to operate with gutter at the left size of the control."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), TypeConverter(typeof(ExpandableObjectConverter))]
        public virtual Gutter Gutter {
            get {
                return this.gutter;
            }
            set {
                if (this.gutter != value) {
                    this.gutter = value;
                    this.OnGutterChanged();
                }
            }
        }
        [Category("SyntaxEdit"), Description("Represents an object that implements \"IMargin\" interface and specifies appearance of vertical line drawn over the text and used to mark some limit, for example, of the maximum string length allowed."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), TypeConverter(typeof(ExpandableObjectConverter))]
        public virtual Margin EditMargin {
            get {
                return this.margin;
            }
            set {
                if (this.margin != value) {
                    this.margin = value;
                    this.OnEditMarginChanged();
                }
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual Painter Painter {
            get {
                return this.painter222;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual KeyList KeyList {
            get {
                return this.keyList;
            }
        }
        [Category("SyntaxEdit"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Editor("QWhale.Design.LineStylesEditor, QWhale.Design", typeof(UITypeEditor)), TypeConverter("QWhale.Design.LineStylesConverter, QWhale.Design")]
        public virtual EditLineStyles LineStyles {
            get {
                return this.lineStyles;
            }
            set {
                if (this.lineStyles != value) {
                    this.lineStyles = value;
                    this.OnLineStylesChanged();
                }
            }
        }

        [Category("SyntaxEdit"), Description("Represents an object that implements \"IWhiteSpace\" interface. This object specifies appearance of white space characters, as well as End-of-line and End-of-file marks."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), TypeConverter(typeof(ExpandableObjectConverter))]
        public virtual WhiteSpace WhiteSpace {
            get {
                return this.whiteSpace;
            }
            set {
                if (this.whiteSpace != value) {
                    this.whiteSpace = value;
                    this.OnWhiteSpaceChanged();
                }
            }
        }
        [Category("SyntaxEdit"), Description("Represents an object that implements \"ILineSeparator\" interface containing methods and properties necessary to separate lines and highlight current line within the control."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), TypeConverter(typeof(ExpandableObjectConverter))]
        public virtual LineSeparator LineSeparator {
            get {
                return this.lineSeparator;
            }
            set {
                if (this.lineSeparator != value) {
                    this.lineSeparator = value;
                    this.OnLineSeparatorChanged();
                }
            }
        }
        [Category("SyntaxEdit"), Description("Represents an object that implements \"IOutlining\" interface that specifies appearance and behaviour of outline sections within the control."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), TypeConverter(typeof(ExpandableObjectConverter))]
        public virtual Outlining Outlining {
            get {
                return this.outlining;
            }
            set {
                if (this.outlining != value) {
                    this.outlining = value;
                    this.OnOutliningChanged();
                }
            }
        }
        [Category("SyntaxEdit"), Description("Represents an object that implements \"IEditBraceMatching\" interface allowing to change appearance of matching braces within the control."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), TypeConverter(typeof(ExpandableObjectConverter))]
        public virtual Braces Braces {
            get {
                return this.braces;
            }
            set {
                if (this.braces != value) {
                    this.braces = value;
                    this.OnBracesChanged();
                }
            }
        }
        [Category("SyntaxEdit"), Description("Represents object that implements \"IEditHyperText\" interface allowing to customize appearance and behaviour of hypertext sections within the control."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), TypeConverter(typeof(ExpandableObjectConverter))]
        public virtual EditHyperText HyperText {
            get {
                return this.hyperText;
            }
            set {
                if (this.hyperText != value) {
                    this.hyperText = value;
                    this.OnHyperTextChanged();
                }
            }
        }
        [Category("SyntaxEdit"), Description("Represents object that implements \"IEditSpelling\" interface containing properties and methods to check control's content spelling and highlight mispelled words."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), TypeConverter(typeof(ExpandableObjectConverter))]
        public virtual EditSpelling Spelling {
            get {
                return this.spelling;
            }
            set {
                if (this.spelling != value) {
                    this.spelling = value;
                    this.OnSpellingChanged();
                }
            }
        }
        [Category("SyntaxEdit"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), TypeConverter(typeof(ExpandableObjectConverter))]
        public virtual Scrolling Scrolling {
            get {
                return this.scrolling;
            }
            set {
                if (this.scrolling != value) {
                    this.scrolling = value;
                    this.OnScrollingChanged();
                }
            }
        }
        [Category("SyntaxEdit"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), TypeConverter(typeof(ExpandableObjectConverter))]
        public virtual EditSyntaxPaint SyntaxPaint {
            get {
                return this.syntaxPaint;
            }
            set {
                if (this.syntaxPaint != value) {
                    this.syntaxPaint = value;
                    this.OnSyntaxPaintChanged();
                }
            }
        }

        [Category("Behavior"), DefaultValue(true), Description("Gets or set a boolean value that indicates whether TAB key should be accepted by Edit control as input key.")]
        public virtual bool AcceptTabs {
            get {
                return this.acceptTabs;
            }
            set {
                if (this.acceptTabs != value) {
                    this.acceptTabs = value;
                    this.OnAcceptTabsChanged();
                }
            }
        }
        [Category("Behavior"), DefaultValue(true), Description("Gets or set a boolean value that indicates whether Enter key should be accepted by Edit control as input key.")]
        public virtual bool AcceptReturns {
            get {
                return this.acceptReturns;
            }
            set {
                if (this.acceptReturns != value) {
                    this.acceptReturns = value;
                    this.OnAcceptReturnsChanged();
                }
            }
        }
        [Category("Appearance"), DefaultValue(EditBorderStyle.Fixed3D), Description("Gets or sets the border style for the Edit control.")]
        public virtual EditBorderStyle BorderStyle {
            get {
                return this.borderStyle;
            }
            set {
                if (this.borderStyle != value) {
                    this.borderStyle = value;
                    this.OnBorderStyleChanged();
                }
            }
        }
        [Category("Appearance"), Description("Gets or sets the border color for the Edit control.")]
        public virtual Color BorderColor {
            get {
                return this.borderColor;
            }
            set {
                if (this.borderColor != value) {
                    this.borderColor = value;
                    this.OnBorderColorChanged();
                }
            }
        }
        [Category("Appearance"), DefaultValue(0), Description("Gets or sets line space between individual lines in the Edit control.")]
        public virtual int LineSpace {
            get {
                return this.lineSpace;
            }
            set {
                if (this.lineSpace != value) {
                    this.lineSpace = value;
                }
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual int ClientWidth {
            get {
                return this.GetClientWidth(false);
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual int ClientHeight {
            get {
                return this.GetClientRect(true).Height;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual int CharsInWidth {
            get {
                return this.GetCharsInWidth(this.GetClientWidth(true));
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual int LinesInHeight {
            get {
                return this.GetLinesInHeight(this.ClientHeight);
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual Rectangle ClientRect {
            get {
                return this.GetClientRect(false);
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual Rectangle ClientArea {
            get {
                return this.GetClientRect(true);
            }
        }
        [Category("Appearance"), DefaultValue(false), Description("Gets or sets a boolean value that indicates whether Edit control should draw its background.")]
        public virtual bool Transparent {
            get {
                return this.transparent;
            }
            set {
                if (this.transparent != value) {
                    this.transparent = value;
                    this.OnTransparentChanged();
                }
            }
        }
        [Category("Behavior"), DefaultValue(true), Description("Indicates whether edit control should use bultin popup menu.")]
        public virtual bool UseDefaultMenu {
            get {
                return this.useDefaultMenu;
            }
            set {
                if (this.useDefaultMenu != value) {
                    this.useDefaultMenu = value;
                    this.OnUseDefaultMenuChanged();
                }
            }
        }
        [Category("SyntaxEdit"), Description("Represents \"Lines\" property in the form of array of strings."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), TypeConverter(typeof(CollectionConverter))]
        public string[] Strings {
            get {
                TextStrings lines = this.Source.Lines;
                string[] array = new string[lines.Count];
                for (int i = 0; i < lines.Count; i++) {
                    array[i] = lines[i];
                }
                return array;
            }
            set {
                TextStrings lines = this.Source.Lines;
                this.Source.BeginUpdate(UpdateReason.Other);
                lines.BeginUpdate();
                try {
                    lines.Clear();
                    for (int i = 0; i < value.Length; i++) {
                        string item = value[i];
                        lines.Add(item);
                    }
                    this.Source.State |= NotifyState.CountChanged;
                    lines.Changed(0, int.MaxValue);
                } finally {
                    lines.EndUpdate();
                    this.Source.EndUpdate();
                }
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public EventHandlers EventHandlers {
            get {
                return this.keyList.Handlers;
            }
        }

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public OutlineRange ActiveOutlineRange {
            get {
                return this.activeOutlineRange;
            }
        }

        [Category("SyntaxEdit"), DefaultValue(null), Description("Gets or sets object that can make lexical analysis for the control's content.")]
        public virtual Circus.Syntax.Lexer.Lexer Lexer {
            get {
                return this.Source.Lexer;
            }
            set {
                this.Source.Lexer = value;
            }
        }

        [Category("Behavior"), DefaultValue(false), Description("Specifies that edit control should highlight current block..")]
        public virtual bool HighlightCurrentBlock {
            get {
                return this.highlightCurrentBlock;
            }
            set {
                if (this.highlightCurrentBlock != value) {
                    this.highlightCurrentBlock = value;
                    this.UpdateCurrentBlock();
                }
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Range CurrentBlockRange {
            get {
                return this.currentBlockRange;
            }
        }
        [Category("Behavior"), Description("Gets or sets navigating options."), Editor("QWhale.Design.FlagEnumerationEditor, QWhale.Design", typeof(UITypeEditor))]
        public virtual NavigateOptions NavigateOptions {
            get {
                return this.Source.NavigateOptions;
            }
            set {
                this.Source.NavigateOptions = value;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual Point Position {
            get {
                return this.Source.Position;
            }
            set {
                this.Source.Position = value;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual Point PrevPosition {
            get {
                return this.Source.PrevPosition;
            }
        }
        [Category("Behavior"), DefaultValue(false), Description("Gets or sets a value indicating whether the control's content is read-only.")]
        public virtual bool ReadOnly {
            get {
                return this.Source.ReadOnly;
            }
            set {
                this.Source.ReadOnly = value;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual bool Overwrite {
            get {
                return this.Source.Overwrite;
            }
            set {
                this.Source.Overwrite = value;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual bool Modified {
            get {
                return this.Source.Modified;
            }
            set {
                this.Source.Modified = value;
            }
        }
        [Category("Behavior"), DefaultValue(false), Description("Gets or sets a value indicating whether the control accepts only one line of the text.")]
        public virtual bool SingleLineMode {
            get {
                return this.Source.SingleLineMode;
            }
            set {
                this.Source.SingleLineMode = value;
            }
        }
        [Category("Behavior"), Description("Gets or sets \"QWhale.Editor.IndentOptions\" for this class, allowing to customize behaior of Edit control when user presses Enter to insert new text line."), Editor("QWhale.Design.FlagEnumerationEditor, QWhale.Design", typeof(UITypeEditor))]
        public virtual IndentOptions IndentOptions {
            get {
                return this.Source.IndentOptions;
            }
            set {
                this.Source.IndentOptions = value;
            }
        }
        
        [Category("Appearance"), DefaultValue(false), Description("Gets or sets a value indicating whether control automatically wraps words to the beginning of the next line when necessary.")]
        public virtual bool WordWrap {
            get {
                return this.displayLines.WordWrap;
            }
            set {
                this.displayLines.WordWrap = value;
            }
        }
        [Category("Appearance"), DefaultValue(false), Description("Gets or sets a value indicating whether control automatically wraps words at margin position.")]
        public virtual bool WrapAtMargin {
            get {
                return this.displayLines.WrapAtMargin;
            }
            set {
                this.displayLines.WrapAtMargin = value;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual int WrapMargin {
            get {
                return this.displayLines.WrapMargin;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual string LineTerminator {
            get {
                return this.Lines.LineTerminator;
            }
            set {
                this.Lines.LineTerminator = value;
            }
        }
        protected Timer CodeCompletionTimer {
            get {
                if (this.codeCompletionTimer == null) {
                    this.codeCompletionTimer = new Timer();
                    this.codeCompletionTimer.Enabled = false;
                    this.codeCompletionTimer.Interval = EditConsts.DefaultHintDelay;
                    this.codeCompletionTimer.Tick += new EventHandler(this.OnCodeCompletion);
                    this.components.Add(this.codeCompletionTimer);
                }
                return this.codeCompletionTimer;
            }
        }
        protected virtual bool IsFocused {
            get {
                return this.Focused || this.IsCodeCompletionWindowFocused;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual bool IsCodeCompletionWindowFocused {
            get {
                return false;
                Control control;
                return this.CodeCompletionWindowFocused(out control);
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual CodeCompletionBox CodeCompletionBox {
            get {
                if (this.codeCompletionBox == null) {
                    this.codeCompletionBox = this.CreateCodeCompletionBox();
                    this.codeCompletionBox.ClosePopup += new ClosePopupEvent(this.CloseCodeCompletionBox);
                    this.codeCompletionBox.Disposed += new EventHandler(this.DisposeCodeCompletionBox);
                }
                return this.codeCompletionBox;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual CodeCompletionHint CodeCompletionHint {
            get {
                if (this.codeCompletionHint == null) {
                    this.codeCompletionHint = this.CreateCodeCompletionHint();
                    this.codeCompletionHint.ClosePopup += new ClosePopupEvent(this.CloseCodeCompletionHint);
                    this.codeCompletionHint.Disposed += new EventHandler(this.DisposeCodeCompletionBox);
                }
                return this.codeCompletionHint;
            }
        }
        [Category("SyntaxEdit"), Description("Represents a collection of characters that initializes a code completion procedure when typing in the editor.")]
        public virtual char[] CodeCompletionChars {
            get {
                return this.codeCompletionChars;
            }
            set {
                if (this.codeCompletionChars != value) {
                    this.codeCompletionChars = value;
                    this.OnCodeCompletionCharsChanged();
                }
            }
        }
       [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual CodeEditor VertSplitEdit {
            get {
                return this.vertSplitEdit;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual CodeEditor HorzSplitEdit {
            get {
                return this.horzSplitEdit;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual Splitter VertSplitter {
            get {
                return this.vertSplitter;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual Splitter HorzSplitter {
            get {
                return this.horzSplitter;
            }
        }
    
        protected override void Dispose(bool disposing) {
            if (disposing) {
                if (this.searchDialog != null) {
                    this.searchDialog.DoneSearch(this);
                }
                this.displayLines = null;
                this.Source = null;
                this.StopCodeCompletionThread();
                if (this.components != null) {
                    this.components.Dispose();
                }
                if (this.innerTextSource != null) {
                    ((IDisposable)this.innerTextSource).Dispose();
                    this.innerTextSource = null;
                }

                uninitScrollBars();

                if (this.margin != null) {
                    this.margin.Dispose();
                    this.margin = null;
                }
                if (this.gutter != null) {
                    this.gutter.Dispose();
                    this.gutter = null;
                }
                if (this.selection != null) {
                    this.selection.Dispose();
                    this.selection = null;
                }
                if (this.printing != null) {
                    this.printing.Dispose();
                    this.printing = null;
                }
                if (this.incrementalSearchCursor != null) {
                    this.incrementalSearchCursor.Dispose();
                    this.incrementalSearchCursor = null;
                }
                if (this.reverseIncrementalSearchCursor != null) {
                    this.reverseIncrementalSearchCursor.Dispose();
                    this.reverseIncrementalSearchCursor = null;
                }
                if (this.codeCompletionBox != null) {
                    this.codeCompletionBox.ClosePopup -= new ClosePopupEvent(this.CloseCodeCompletionBox);
                    this.codeCompletionBox.Disposed -= new EventHandler(this.DisposeCodeCompletionBox);
                    ((IDisposable)this.codeCompletionBox).Dispose();
                    this.codeCompletionBox = null;
                }
                if (this.codeCompletionHint != null) {
                    this.codeCompletionHint.ClosePopup -= new ClosePopupEvent(this.CloseCodeCompletionHint);
                    this.codeCompletionHint.Disposed -= new EventHandler(this.DisposeCodeCompletionBox);
                    ((IDisposable)this.codeCompletionHint).Dispose();
                    this.codeCompletionHint = null;
                }
                SearchManager.SharedSearch.Done(this);
            }
            base.Dispose(disposing);
        }


        private void PaintScrollRect(Painter painter) {
            if (this.scrolling.owner.hasVScrollBar && this.scrolling.owner.hasHScrollBar) {
                Rectangle rect = new Rectangle(base.ClientRectangle.Right - this.scrolling.owner.vScrollBar.Width, base.ClientRectangle.Bottom - this.scrolling.owner.hScrollBar.Height, this.scrolling.owner.vScrollBar.Width, this.scrolling.owner.hScrollBar.Height);
                Color backColor = this.Painter.BackColor;
                try {
                    painter.BackColor = SystemColors.Control;
                    painter.FillRectangle(rect);
                    painter.ExcludeClipRect(rect.Left, rect.Top, rect.Width, rect.Height);
                } finally {
                    painter.BackColor = backColor;
                }
            }
        }

        protected void CancelDragging() {
            this.dragMargin = false;
            this.margin.CancelDragging();
        }
        protected void StartTripleClickTimer() {
            if (this.tripleClickTimer == null) {
                this.tripleClickTimer = new Timer();
                this.tripleClickTimer.Interval = SystemInformation.DoubleClickTime;
                this.tripleClickTimer.Tick += new EventHandler(this.DoTripleClick);
            }
            this.tripleClickTimer.Enabled = true;
        }
        protected void StopTripleClickTimer() {
            if (this.tripleClickTimer != null) {
                this.tripleClickTimer.Stop();
            }
            this.lbuttonClicks = 0;
        }
        protected void DoTripleClick(object sender, EventArgs e) {
            this.StopTripleClickTimer();
        }
        protected bool IsSignificantMouseMove(Point pt1, Point pt2) {
            return Math.Abs(pt1.X - pt2.X) > 1 || Math.Abs(pt1.Y - pt2.Y) > 1;
        }
        protected virtual void UpdateMonospaced() {
            if (this.Lexer != null) {
                foreach (LexStyle current in this.Lexer.Scheme.Styles) {
                    this.painter222.fontStyle = current.FontStyle;
                }
            }
            if (this.Braces.BracesOptions != BracesOptions.None) {
                this.painter222.fontStyle = this.Braces.FontStyle;
            }
        }
        protected void DoFontChanged() {
            this.painter222.Clear();
            this.painter222.font = this.Font;
            this.UpdateMonospaced();
            if (!this.gutter.InvalidateLineNumberArea(true) || !this.WordWrap) {
                this.UpdateWordWrap();
            }
            this.UpdateView();
        }
        protected void StartDragging() {
            this.saveDragPos = this.Position;
            if (!this.selection.IsEmpty) {
                DragDropEffects dragDropEffects = base.DoDragDrop(this.selection.SelectedText, DragDropEffects.All);
                if (dragDropEffects == DragDropEffects.Move) {
                    this.selection.Delete();
                }
                this.needStartDrag = false;
                this.selection.SelectionState = SelectionState.None;
            }
        }
 
        private bool CheckCursor(Point pt) {
            return false;
            Cursor cursor = null;
            HitTestInfo hitTestInfo = new HitTestInfo();
            this.GetHitTest(pt, hitTestInfo);
            if ((hitTestInfo.HitTest & HitTest.Left) != HitTest.None || (hitTestInfo.HitTest & HitTest.Right) != HitTest.None || (hitTestInfo.HitTest & HitTest.Above) != HitTest.None || (hitTestInfo.HitTest & HitTest.Below) != HitTest.None) {
                cursor = Cursors.Arrow;
            } else {
                if ((hitTestInfo.HitTest & HitTest.Gutter) != HitTest.None) {
                    if (((hitTestInfo.HitTest & HitTest.OutlineArea) != HitTest.None && (hitTestInfo.HitTest & HitTest.OutlineImage) == HitTest.None) || ((hitTestInfo.HitTest & HitTest.LineNumber) != HitTest.None && (this.gutter.Options & GutterOptions.PaintLinesOnGutter) == GutterOptions.None)) {
                        cursor = this.LeftArrowCursor;
                    } else {
                        cursor = Cursors.Arrow;
                    }
                } else {
                    if ((hitTestInfo.HitTest & HitTest.Margin) != HitTest.None && this.margin.AllowDrag && (Control.ModifierKeys & Keys.Control) != Keys.None) {
                        cursor = Cursors.SizeWE;
                    } else {
                        if ((hitTestInfo.HitTest & HitTest.HyperText) != HitTest.None && (Control.ModifierKeys & Keys.Control) != Keys.None) {
                            cursor = Cursors.Hand;
                        } else {
                            if (this.InIncrementalSearch) {
                                if ((this.searchOptions & SearchOptions.BackwardSearch) != SearchOptions.None) {
                                    cursor = this.ReverseIncrementalSearchCursor;
                                } else {
                                    cursor = this.IncrementalSearchCursor;
                                }
                            } else {
                                if ((hitTestInfo.HitTest & HitTest.Selection) != HitTest.None) {
                                    cursor = Cursors.Arrow;
                                }

                            }
                        }
                    }
                }
            }
            if (cursor != null) {
                Win32Api.SetCursor(cursor.Handle);
            }
            return cursor != null;
        }
        protected bool NeedResizeRedraw() {
            return (this.scrolling.owner.hasVScrollBar && this.scrolling.owner.hasHScrollBar) || ((this.selection.Options & SelectionOptions.DrawBorder) != SelectionOptions.None && (this.selection.Options & SelectionOptions.SelectBeyondEol) != SelectionOptions.None && this.selection.owner.selectionBorderColor != Color.Empty);
        }
        protected bool NeedImeComposition() {
            return base.IsHandleCreated && base.ImeMode != ImeMode.Disable && base.ImeMode != ImeMode.NoControl && base.ImeMode != ImeMode.Off;
        }
        protected void InternalProcessKey(char ch) {
            byte b = this.TextStyleAt(new Point(Math.Max(this.Position.X - 1, 0), this.Position.Y));
            bool flag = b == 0 || this.IsValidText((byte)(b - 1));
            if (this.CodeCompletion(ch, b, flag) || (flag && (this.Selection.SmartFormat(ch) || this.Selection.SmartIndent(ch)))) {
            }
        }
        protected void QueryEndDrag(object sender, QueryContinueDragEventArgs e) {
            if (e.Action == DragAction.Cancel || e.Action == DragAction.Drop || e.EscapePressed) {
                this.needStartDrag = false;
            }
            if (e.Action == DragAction.Cancel || e.EscapePressed) {
                this.Selection.BeginUpdate();
                try {
                    this.HideDragCaret();
                    this.Source.Position = this.saveDragPos;
                } finally {
                    this.Selection.EndUpdate();
                }
            }
        }
      
        protected bool ProcessKey(Keys keyData) {
            //if (keyData == Keys.A) {
            //    input('a');
            //} 
            //if (keyData == Keys.B) {
            //    input('b');
            //}
            return false;
            //bool result;
            //if (this.keyList.ExecuteKey(keyData, ref this.keyState)) {
            //    result = true;
            //} else {
            //    if ((keyData & (Keys)65518) != Keys.None) {
            //        this.keyState = 0;
            //    }
            //    result = false;
            //}
            //return result;
        }
        protected override void OnEnabledChanged(EventArgs e) {
            base.OnEnabledChanged(e);
            base.Invalidate();
        }
        public override bool PreProcessMessage(ref Message msg) {
            bool result;
            if (msg.Msg == 260) {
                Keys keyData = Control.ModifierKeys | (Keys)(msg.WParam.ToInt32() & 65535);
                if (this.ProcessKey(keyData)) {
                    result = true;
                    return result;
                }
            }
            result = base.PreProcessMessage(ref msg);
            return result;
        }
        private void ScrollTo(Point position, bool centerLine) {
            int count = this.displayLines.Count;
            Point point = this.TextToScreen(position);
            if (this.scrolling.ScrollByPixels) {
                Rectangle clientRect = this.ClientRect;

                {
                    clientRect.X += this.gutter.DisplayWidth;
                    clientRect.Width -= this.gutter.DisplayWidth;
                }
                if (point.X < clientRect.Left) {
                    this.scrolling.WindowOriginX += point.X - clientRect.Left;
                } else {
                    int width = this.GetCaretSize(position).Width;
                    if (point.X > clientRect.Right - width) {
                        this.scrolling.WindowOriginX += Math.Max(point.X - clientRect.Right + width, 1);
                    }
                }
                if (point.Y < clientRect.Top) {
                    if (centerLine) {
                        this.scrolling.WindowOriginY += point.Y - clientRect.Height / 2;
                    } else {
                        this.scrolling.WindowOriginY += point.Y - clientRect.Top;
                    }
                } else {
                    if (point.Y > clientRect.Bottom - this.painter222.lineHeight) {
                        if (centerLine) {
                            this.scrolling.WindowOriginY += point.Y - (clientRect.Height - this.painter222.lineHeight) / 2;
                        } else {
                            this.scrolling.WindowOriginY += point.Y - clientRect.Height + this.painter222.lineHeight;
                        }
                    }
                }
            } else {
                position = this.displayLines.PointToDisplayPoint(position);
                int num = position.X - this.scrolling.WindowOriginX;
                int num2 = position.Y - this.scrolling.WindowOriginY;
                if (num < 0) {
                    this.scrolling.WindowOriginX = position.X - (((this.scrolling.Options & ScrollingOptions.UseScrollDelta) != ScrollingOptions.None) ? 1 : 0);
                } else {
                    int width = this.GetCaretSize(this.Position).Width;
                    int num3 = this.ClientRect.Right;
                    if (point.X > num3 - width) {
                        if ((this.scrolling.Options & ScrollingOptions.UseScrollDelta) != ScrollingOptions.None) {
                            num3 -= num3 / EditConsts.DefaultScrollDeltaRatio;
                        }
                        this.scrolling.WindowOriginX += Math.Max(this.GetCharsInWidth(point.X - num3 + width, false), 1);
                    }
                }
                if (num2 < 0) {
                    if (centerLine) {
                        this.scrolling.WindowOriginY += this.GetLinesInHeight(point.Y - this.ClientHeight / 2);
                    } else {
                        this.scrolling.WindowOriginY = position.Y;
                    }
                } else {
                    if (num2 > this.LinesInHeight - 1) {
                        if (centerLine) {
                            this.scrolling.WindowOriginY += this.GetLinesInHeight(point.Y - this.ClientHeight / 2);
                        } else {
                            this.scrolling.WindowOriginY += num2 - this.LinesInHeight + 1;
                        }
                        if (count != this.displayLines.Count) {
                            this.scrolling.UpdateScroll();
                        }
                    }
                }
            }
        }
        protected Point TextToScreen(int x, int y, bool lineEnd) {
            Point point = this.displayLines.PointToDisplayPoint(x, y, lineEnd);
            return this.DisplayToScreen(point.X, point.Y);
        }
        protected int GetCharsInWidth(int width, bool exact) {
            int fontWidth = this.painter222.FontWidth;
            int result;
            if (fontWidth == 0) {
                result = 0;
            } else {
                int num = width / fontWidth;
                if (!exact && width % fontWidth != 0) {
                    num++;
                }
                result = num;
            }
            return result;
        }
        protected int GetClientWidth(bool charWidth) {
            return this.GetClientRect(true).Width - (charWidth ? this.gutter.DisplayArea : this.gutter.DisplayWidth);
        }
        protected Rectangle GetClientRect(bool excludeNonClient) {
            return Rectangle.Empty;
            Rectangle clientRectangle = base.ClientRectangle;

            if (this.scrolling.owner.hasVScrollBar) {
                clientRectangle.Width -= this.scrolling.owner.vScrollBar.Width;
            }
            if (this.scrolling.owner.hasHScrollBar) {
                clientRectangle.Height -= this.scrolling.owner.hScrollBar.Height;
            }
            return clientRectangle;
        }

        protected bool IsMouseOnSyntaxError(int x, int y, out SyntaxError err) {
            err = null;
            Point point = this.ScreenToText(x, y);
            if (point.Y >= 0 && point.Y < this.Lines.Count) {
                StringItem item = this.Lines.GetItem(point.Y);
                if (point.X >= 0) {
                    TextStyle textStyle = TextStyle.None;
                    if (point.X < item.String.Length) {
                        textStyle = item.TextStyleAt(point.X);
                    } else {
                        if (point.X == item.String.Length) {
                            textStyle = TextStyle.WaveLine;
                        }
                    }
                    if ((byte)(textStyle & (TextStyle.MisSpelledWord | TextStyle.WaveLine)) != 0) {
                        err = this.Source.GetSyntaxErrorAt(point.X, point.Y);
                    }
                }
            }
            return err != null;
        }
        protected int ScreenToDisplayX(int x, int line) {
            int width;

            {
                if (this.scrolling.ScrollByPixels) {
                    width = -this.ClientRect.Left + this.scrolling.WindowOriginX + x - this.gutter.DisplayWidth;
                } else {
                    width = -this.ClientRect.Left + this.painter222.FontWidth * this.scrolling.WindowOriginX + x - this.gutter.DisplayWidth;
                }
            }
            int val = 0;
            this.syntaxPaint.MeasureLine(line, 0, -1, width, out val, false);
            return Math.Max(val, 0);
        }
        protected void ClearActiveOutlineRange() {
            if (this.activeOutlineRange != null) {
                this.BeginUpdate();
                try {
                    this.InvalidateWindow(this.activeOutlineRange.StartPoint.Y, this.activeOutlineRange.EndPoint.Y, true);
                    this.activeOutlineRange = null;
                } finally {
                    this.EndUpdate();
                }
            }
        }
        private void UpdateActiveOutlineRange() {
            bool flag = false;
            if (this.Outlining.AllowOutlining && (this.Outlining.OutlineOptions & OutlineOptions.HighlightOnMove) != OutlineOptions.None) {
                Point position = base.PointToClient(Cursor.Position);
                HitTestInfo hitTestInfo = new HitTestInfo();
                this.GetHitTest(position, hitTestInfo);
                if ((hitTestInfo.HitTest & HitTest.Gutter) != HitTest.None) {
                    if ((hitTestInfo.HitTest & HitTest.OutlineArea) != HitTest.None && (hitTestInfo.HitTest & HitTest.LineModificator) == HitTest.None) {
                        flag = true;
                    }
                }
                if (flag) {
                    int num = this.scrolling.WindowOriginY + this.GetLinesInHeight(position.Y - this.ClientRect.Top);
                    position = this.ScreenToText(position.X, position.Y);
                    OutlineRange outlineRange = (num >= this.displayLines.DisplayCount) ? null : this.Outlining.GetOutlineRange(position.Y);
                    if (this.activeOutlineRange != outlineRange) {
                        try {
                            this.BeginUpdate();
                            if (this.activeOutlineRange != null) {
                                this.ClearActiveOutlineRange();
                            }
                            this.activeOutlineRange = outlineRange;
                            if (this.activeOutlineRange != null) {
                                this.InvalidateWindow(this.activeOutlineRange.StartPoint.Y, this.activeOutlineRange.EndPoint.Y, true);
                            }
                        } finally {
                            this.EndUpdate();
                        }
                    }
                } else {
                    this.ClearActiveOutlineRange();
                }
            }
        }
        protected virtual void OnSelectionChanged() {
        }
        protected virtual void OnGutterChanged() {
        }
        protected virtual void OnEditMarginChanged() {
        }
        protected virtual void OnLineStylesChanged() {
        }
        protected virtual void OnPrintingChanged() {
        }
        protected virtual void OnWhiteSpaceChanged() {
        }
        protected virtual void OnLineSeparatorChanged() {
        }
        protected virtual void OnOutliningChanged() {
        }
        protected virtual void OnBracesChanged() {
        }
        protected virtual void OnHyperTextChanged() {
        }
        protected virtual void OnSpellingChanged() {
        }
        protected virtual void OnScrollingChanged() {
        }
        protected virtual void OnSyntaxPaintChanged() {
        }
        protected virtual void OnAcceptTabsChanged() {
        }
        protected virtual void OnAcceptReturnsChanged() {
        }
        protected virtual void OnUseDefaultMenuChanged() {
        }
        protected virtual void OnPagesChanged() {
        }
        protected virtual void OnBorderStyleChanged() {
            base.RecreateHandle();
        }
        protected virtual void OnBorderColorChanged() {
            base.RecreateHandle();
        }
     
        protected void OnTransparentChanged() {
            base.SetStyle(ControlStyles.Opaque, !this.IsTransparent);
            base.SetStyle(ControlStyles.DoubleBuffer, this.IsTransparent);
            base.Invalidate();
        }
        protected virtual void OnDefaultMenuChanged() {
        }
        protected void DoUndo(object sender, EventArgs e) {
            if (this.Source.CanUndo()) {
                this.Source.Undo();
            }
        }
        protected void DoRedo(object sender, EventArgs e) {
            if (this.Source.CanRedo()) {
                this.Source.Redo();
            }
        }
        protected void DoCut(object sender, EventArgs e) {
            if (this.Selection.CanCut()) {
                this.Selection.Cut();
            }
        }
        protected void DoCopy(object sender, EventArgs e) {
            if (this.Selection.CanCopy()) {
                this.Selection.Copy();
            }
        }
        protected void DoPaste(object sender, EventArgs e) {
            if (this.Selection.CanPaste()) {
                this.Selection.Paste();
            }
        }
        protected void DoDelete(object sender, EventArgs e) {
            this.Selection.DeleteRight();
        }
        protected void DoSelectAll(object sender, EventArgs e) {
            this.Selection.SelectAll();
        }
        protected virtual void InitDefaultMenu() {
            this.defaultMenu = new ContextMenuStrip();
            this.miUndo = new ToolStripMenuItem(StringConsts.MenuUndoCaption, null, new EventHandler(this.DoUndo));
            this.miRedo = new ToolStripMenuItem(StringConsts.MenuRedoCaption, null, new EventHandler(this.DoRedo));
            this.miCut = new ToolStripMenuItem(StringConsts.MenuCutCaption, null, new EventHandler(this.DoCut));
            this.miCopy = new ToolStripMenuItem(StringConsts.MenuCopyCaption, null, new EventHandler(this.DoCopy));
            this.miPaste = new ToolStripMenuItem(StringConsts.MenuPasteCaption, null, new EventHandler(this.DoPaste));
            this.miDelete = new ToolStripMenuItem(StringConsts.MenuDeleteCaption, null, new EventHandler(this.DoDelete));
            this.miSelectAll = new ToolStripMenuItem(StringConsts.MenuSelectAllCaption, null, new EventHandler(this.DoSelectAll));
            this.defaultMenu.Items.Add(this.miUndo);
            this.defaultMenu.Items.Add(this.miRedo);
            this.defaultMenu.Items.Add("-");
            this.defaultMenu.Items.Add(this.miCut);
            this.defaultMenu.Items.Add(this.miCopy);
            this.defaultMenu.Items.Add(this.miPaste);
            this.defaultMenu.Items.Add(this.miDelete);
            this.defaultMenu.Items.Add("-");
            this.defaultMenu.Items.Add(this.miSelectAll);
        }
        protected virtual void UpdateMenu() {
            this.miUndo.Enabled = this.Source.CanUndo();
            this.miRedo.Enabled = this.Source.CanRedo();
            this.miCut.Enabled = this.Selection.CanCut();
            this.miCopy.Enabled = this.Selection.CanCopy();
            this.miPaste.Enabled = this.Selection.CanPaste();
            this.miDelete.Enabled = (this.Text != string.Empty);
        }
        protected virtual void PopupDefaultMenu(Point pos) {
            if (this.useDefaultMenu) {
                if (this.defaultMenu == null) {
                    this.InitDefaultMenu();
                }
                this.UpdateMenu();
                this.defaultMenu.Show(this, pos);
            }
        }
        public virtual bool ProcessKeyMsg(ref Message msg) {
            bool flag = this.PreProcessMessage(ref msg);
            bool result;
            if (!flag) {
                result = this.ProcessKeyMessage(ref msg);
            } else {
                result = flag;
            }
            return result;
        }
        public virtual Point ScreenToText(Point position) {
            bool flag = false;
            return this.ScreenToText(position.X, position.Y, ref flag);
        }
        public virtual Point ScreenToText(int x, int y, ref bool lineEnd) {
            Point point = this.ScreenToDisplay(x, y);
            return this.displayLines.DisplayPointToPoint(point.X, point.Y, ref lineEnd);
        }
        public virtual Point TextToScreen(Point position) {
            return this.TextToScreen(position.X, position.Y);
        }
        public virtual Point TextToScreen(Point position, bool lineEnd) {
            return this.TextToScreen(position.X, position.Y, lineEnd);
        }
        public virtual Point ScreenToText(int x, int y) {
            bool flag = false;
            return this.ScreenToText(x, y, ref flag);
        }
        public virtual Point TextToScreen(int x, int y) {
            return this.TextToScreen(x, y, this.displayLines.LineEnd);
        }
        public virtual Point ScreenToDisplay(int x, int y) {
            int num;
            int width;

            {
                return Point.Empty;
                Rectangle clientRect2 = this.ClientRect;
                if (this.scrolling.ScrollByPixels) {
                    num = this.GetLinesInHeight(this.scrolling.WindowOriginY + y - clientRect2.Top);
                    width = -clientRect2.Left + this.scrolling.WindowOriginX + x - this.gutter.DisplayWidth;
                } else {
                    num = this.scrolling.WindowOriginY + this.GetLinesInHeight(y - clientRect2.Top);
                    width = -clientRect2.Left + this.painter222.FontWidth * this.scrolling.WindowOriginX + x - this.gutter.DisplayWidth;
                }
            }
            int val = 0;
            if ((this.NavigateOptions & NavigateOptions.BeyondEof) == NavigateOptions.None && num > this.displayLines.DisplayCount - 1) {
                num = Math.Max(this.displayLines.DisplayCount - 1, 0);
            }
            this.syntaxPaint.MeasureLine(num, 0, -1, width, out val, false);
            return new Point(Math.Max(val, 0), Math.Max(num, 0));
        }
        public virtual Point DisplayToScreen(int x, int y) {
            return this.DisplayToScreen(x, y, false);
        }
        public virtual Point DisplayToScreen(int x, int y, bool average) {
            int num = average ? (this.painter222.FontWidth*x) : this.syntaxPaint.MeasureLine(y, 0, x);
            int num2;
            Rectangle clientRect = this.ClientRect;
            if (this.scrolling.ScrollByPixels) {
                num2 = y*this.painter222.lineHeight - this.scrolling.WindowOriginY + clientRect.Top;
                if (num != int.MaxValue) {
                    num = num - this.scrolling.WindowOriginX + this.gutter.DisplayWidth + clientRect.Left;
                }
            } else {
                num2 = (y - this.scrolling.WindowOriginY)*this.painter222.lineHeight + clientRect.Top;
                if (num != int.MaxValue) {
                    num = num - this.painter222.FontWidth*this.scrolling.WindowOriginX + this.gutter.DisplayWidth + clientRect.Left;
                }
            }
            return new Point(num, num2);
        }

        public virtual void MakeVisible(Point position) {
            this.MakeVisible(position, false);
        }
        public virtual void MakeVisible(Point position, bool centerLine) {
            if (base.IsHandleCreated) {
                this.Outlining.EnsureExpanded(position);
                this.ScrollTo(position, centerLine);
            }
        }
        public void UpdateView() {
            this.displayLines.UpdateNeeded();
            this.UpdateCaretMode();
            base.Invalidate();
        }
        public virtual int GetCharsInWidth(int width) {
            int fontWidth = this.painter222.FontWidth;
            int result;
            if (fontWidth == 0) {
                result = 0;
            } else {
                result = width / fontWidth;
            }
            return result;
        }
        public virtual int GetLinesInHeight(int height) {
            int lineHeight = this.painter222.lineHeight;
            int result;
            if (lineHeight == 0) {
                result = 0;
            } else {
                result = height / lineHeight;
            }
            return result;
        }
        public virtual void GetHitTest(Point position, HitTestInfo hitTestInfo) {
            this.GetHitTest(position.X, position.Y, hitTestInfo);
        }
        public virtual void GetHitTest(int x, int y, HitTestInfo hitTestInfo) {
            Rectangle clientRect = this.ClientRect;
            if (x < clientRect.Left) {
                hitTestInfo.HitTest |= HitTest.Left;
            }
            if (x > clientRect.Right) {
                hitTestInfo.HitTest |= HitTest.Right;
            }
            if (y < clientRect.Top) {
                hitTestInfo.HitTest |= HitTest.Above;
            }
            if (y > clientRect.Bottom) {
                hitTestInfo.HitTest |= HitTest.Below;
            }

            if (this.margin.Visible && this.margin.Contains(x, y)) {
                hitTestInfo.HitTest |= HitTest.Margin;
            }
            if ((hitTestInfo.HitTest & HitTest.PageWhiteSpace) == HitTest.None) {
                this.gutter.GetHitTest(x, y, hitTestInfo);
                if ((hitTestInfo.HitTest & HitTest.Gutter) == HitTest.None) {
                    if (this.ScreenToDisplay(x, y).Y >= this.displayLines.Count) {
                        hitTestInfo.HitTest |= HitTest.BeyondEof;
                    } else {
                        this.GetHitTestAtTextPoint(this.ScreenToText(x, y), hitTestInfo);
                    }
                }
            }
        }
        public virtual void GetHitTestAtTextPoint(Point position, HitTestInfo hitTestInfo) {
            this.GetHitTestAtTextPoint(position.X, position.Y, hitTestInfo);
        }
        public virtual void GetHitTestAtTextPoint(int x, int y, HitTestInfo hitTestInfo) {
            if (y >= 0 && y < this.Lines.Count) {
                hitTestInfo.Item = this.Lines.GetItem(y);
                hitTestInfo.String = this.Lines[y];
                hitTestInfo.Line = y;
                hitTestInfo.Pos = x;
                if (x >= 0 && x < hitTestInfo.String.Length) {
                    hitTestInfo.HitTest |= HitTest.Text;
                    hitTestInfo.Style = (int)hitTestInfo.Item.TextData[x].Data;
                    hitTestInfo.TextStyle = hitTestInfo.Item.TextStyleAt(x);
                    hitTestInfo.Word = this.Lines.GetTextAt(x, y);
                    string url;
                    if (this.hyperText.IsUrlAtTextPoint(x, y, out url)) {
                        hitTestInfo.HitTest |= HitTest.HyperText;
                        hitTestInfo.Url = url;
                    }
                } else {
                    hitTestInfo.HitTest |= HitTest.BeyondEol;
                }
            } else {
                hitTestInfo.HitTest |= HitTest.BeyondEof;
            }
            if (this.selection.IsPosInSelection(x, y)) {
                hitTestInfo.HitTest |= HitTest.Selection;
            }
        }
        public virtual string GetTextAtCursor() {
            return this.Lines.GetTextAt(this.Position);
        }

        public virtual void ProcessKeyPress(char keyChar) {
            input(keyChar);
            return;
            if (this.Source.Overwrite) {
                this.Source.DeleteRight(1);
            }
            this.selection.InsertString(keyChar.ToString());
            if (this.macroRecording) {
                this.RecordKeyData(new MacroKeyData(Keys.None, null, this.keyList.Handlers.MacroRecordEvent, keyChar, -1, 0));
            }
        }


        private void OnSourceChanged() {
            if (this.displayLines != null) {
                this.displayLines.Lines = this.Source.Lines;
                this.OnOutlineChanged(true);
                this.MakeVisible(this.Position);
                this.UpdateCaret();
                this.scrolling.UpdateScroll();
                this.selection.Clear();
                base.Invalidate();
            }
        }
        private void RescanLines(int firstLine, int lastLine) {
            this.UpdateWordWrap(firstLine, lastLine);
            this.scrolling.UpdateScroll();
        }
        private void InvalidateWindow(int first, int last, bool invalidateGutter) {
            if (this.syntaxPaint.NeedPaint) {
                base.Invalidate();
            } else {
                Point position = this.TextToScreen(new Point(0, first), false);
                Point position2;
                if (last == int.MaxValue) {
                    position2 = new Point(this.ClientRect.Right, this.ClientRect.Bottom);
                } else {
                    position2 = this.TextToScreen(new Point(int.MaxValue, last), true);
                    position2.Y += this.painter222.lineHeight;
                }

                {
                    if (invalidateGutter && this.gutter.DisplayWidth > 0) {
                        position.X = this.ClientRect.Left;
                        position2.X = this.ClientRect.Right;
                    }
                }
                position2.X = this.ClientRect.Right;
                if (invalidateGutter) {
                    if (position.Y > 0) {
                        position.Y--;
                    }
                    position2.Y++;
                }
                base.Invalidate(new Rectangle(position.X, position.Y, position2.X - position.X + 1, position2.Y - position.Y + 1));
                this.syntaxPaint.NeedPaint = true;
            }
        }
        private void OnOutlineChanged(bool update) {
            if (this.outlining.AllowOutlining) {
                if (this.Source.NeedOutlineText()) {
                    SyntaxParser syntaxParser = (SyntaxParser)this.Source.Lexer;
                    List<Range> ranges = new List<Range>();
                    syntaxParser.Outline(ranges);
                    this.outlining.SetOutlineRanges(ranges, true);
                    if (this.Source.ActiveEdit == this) {
                        Point position = this.Position;
                        if (position.X > 0) {
                            position.X--;
                        }
                        this.outlining.EnsureExpanded(position);
                    }
                } else {
                    if (update) {
                        this.outlining.UnOutline();
                    }
                }
            }
        }
        protected void PositionChanged(UpdateReason reason, int deltaX, int deltaY) {
            Point position = this.Position;
            this.displayLines.PositionChanged(reason, position.X, position.Y, deltaX, deltaY);
            this.selection.PositionChanged(this.Position.X, this.Position.Y, deltaX, deltaY);
            if (this.codeCompletionBox != null) {
                this.codeCompletionBox.PositionChanged(this.Position.X, this.Position.Y, deltaX, deltaY);
            }
            if (this.codeCompletionHint != null) {
                this.codeCompletionHint.PositionChanged(this.Position.X, this.Position.Y, deltaX, deltaY);
            }
        }
        protected void OnSourceStateChanged(NotifyState state, int first, int last) {
            if (this.SourceStateChanged != null) {
                this.notifyEventArgs.FirstChanged = first;
                this.notifyEventArgs.LastChanged = last;
                this.notifyEventArgs.State = state;
                this.notifyEventArgs.Update = false;
                this.SourceStateChanged(this, this.notifyEventArgs);
            }
            this.OnStateChanged(this.Source, state);
        }
        protected void OnSyntaxChanged() {
            if (this.outlining.AllowOutlining) {
                if (!this.Source.NeedOutlineText()) {
                    this.outlining.UnOutline();
                }
            }
            this.DoFontChanged();
        }
        protected void OnModifiedChanged() {
            if (this.ModifiedChanged != null) {
                this.ModifiedChanged(this, EventArgs.Empty);
            }
        }
        public virtual void Notification(object sender, EventArgs e) {
            if (sender is Circus.CodeEditor.TextSource.TextSource) {
                Circus.CodeEditor.TextSource.TextSource textSource = (Circus.CodeEditor.TextSource.TextSource)sender;
                if (textSource == this.Source) {
                    NotifyState state = textSource.State;
                    if (e is PositionChangedEventArgs) {
                        PositionChangedEventArgs positionChangedEventArgs = (PositionChangedEventArgs)e;
                        this.PositionChanged(positionChangedEventArgs.Reason, positionChangedEventArgs.DeltaX, positionChangedEventArgs.DeltaY);
                    } else {
                        if (e is BlockDeletingEventArgs) {
                            this.displayLines.BlockDeleting(((BlockDeletingEventArgs)e).Rect);
                        } else {
                            if (e is CodeCompletionArgs) {
                                if (textSource.ActiveEdit == this) {
                                    this.OnNeedCompletion((CodeCompletionArgs)e);
                                }
                            } else {
                                bool flag = (state & NotifyState.BookMarkChanged) != NotifyState.None;
                                bool flag2 = (state & NotifyState.Edit) != NotifyState.None;
                                bool flag3 = (state & NotifyState.ModifiedChanged) != NotifyState.None;
                                bool flag4 = (state & NotifyState.ReadOnlyChanged) != NotifyState.None;
                                bool flag5 = (state & NotifyState.PositionChanged) != NotifyState.None;
                                if (flag5 || flag2) {
                                    this.StopCodeCompletionThread();
                                }
                                if ((state & NotifyState.OverWriteChanged) != NotifyState.None) {
                                    this.UpdateCaretMode();
                                }
                                if ((state & NotifyState.Undo) != NotifyState.None) {
                                    this.ClosePopupWindow();
                                }
                                if (flag2 || flag || (state & NotifyState.BlockChanged) != NotifyState.None) {
                                    if (flag2) {
                                        this.RescanLines(textSource.FirstChanged, textSource.LastChanged);
                                        this.OnTextChanged(EventArgs.Empty);
                                    }
                                    this.InvalidateWindow(textSource.FirstChanged, textSource.LastChanged, flag || this.outlining.AllowOutlining || (this.gutter.Options & GutterOptions.PaintLineNumbers) != GutterOptions.None || (this.gutter.Options & GutterOptions.PaintLineModificators) != GutterOptions.None );
                                }
                                if (flag4) {
                                    base.Invalidate();
                                } else {
                                    if (flag3 && (this.gutter.Options & GutterOptions.PaintLineModificators) != GutterOptions.None) {
                                        base.Invalidate(this.Gutter.Rect);
                                    }
                                }
                                if (flag5 || (state & NotifyState.CenterLine) != NotifyState.None || (state & NotifyState.CountChanged) != NotifyState.None) {
                                    this.CheckIncrementalSeacrh();
                                    if (textSource.ActiveEdit == this) {
                                        textSource.CurrentSnippet = textSource.GetCodeSnippetRangeAt(this.Position);
                                        this.lineSeparator.TempUnhighlightLine();
                                        if ((this.selection.Options & SelectionOptions.SmartFormat) != SelectionOptions.None && textSource.NeedReparseTextOnLineChange() && (state & NotifyState.TextParsed) != NotifyState.None && (state & NotifyState.Undo) == NotifyState.None && (textSource.PrevPosition.Y != textSource.Position.Y || (state & NotifyState.CountChanged) != NotifyState.None)) {
                                            this.selection.SmartFormat(textSource.PrevPosition.Y);
                                        }
                                        if (this.displayLines.UpdateCount == 0) {
                                            this.displayLines.LineEnd = false;
                                        }
                                        this.MakeVisible(this.Position, (state & NotifyState.CenterLine) != NotifyState.None);
                                        this.UpdateCaret();
                                        this.ClearSelection();
                                        this.UpdateStartSearchPos();
                                        this.vertNavigate = false;
                                    }
                                }
                                if ((state & NotifyState.SelectBlock) != NotifyState.None && textSource.ActiveEdit == this) {
                                    if (this.selection.UpdateCount == 0 && (this.selection.Options & SelectionOptions.PersistentBlocks) == SelectionOptions.None) {
                                        this.selection.SetSelection(SelectionType.Stream, textSource.SelectBlockRect);
                                    }
                                }
                                if ((state & NotifyState.CountChanged) != NotifyState.None) {
                                    if (this.gutter.InvalidateLineNumberArea(false)) {
                                        if (!flag4) {
                                            base.Invalidate();
                                        }
                                    }
                                    this.scrolling.UpdateScroll(false);
                                }
                                if ((state & NotifyState.SyntaxChanged) != NotifyState.None) {
                                    this.OnSyntaxChanged();
                                }
                                if ((state & NotifyState.Outline) != NotifyState.None) {
                                    this.OnOutlineChanged(false);
                                }
                                this.OnSourceStateChanged(state, textSource.FirstChanged, textSource.LastChanged);
                                if (flag5) {
                                    this.selection.OnSelectionChanged();
                                }
                                if (flag3) {
                                    this.OnModifiedChanged();
                                }
                            }
                        }
                    }
                }
            } else {
                if (sender == this.displayLines) {
                    NotifyEventArgs notifyEventArgs = (NotifyEventArgs)e;
                    if ((notifyEventArgs.State & NotifyState.Outline) != NotifyState.None && this.displayLines.IsPointVisible(this.Position)) {
                        Range range = null;
                        if (!this.displayLines.IsPointCollapsed(this.Position, out range)) {
                            this.ScrollTo(this.Position, false);
                        } else {
                            if (range != null) {
                                this.MoveTo(range.StartPoint);
                                this.ScrollTo(range.StartPoint, false);
                            }
                        }
                    }
                    if (notifyEventArgs.Update || !this.WordWrap) { }
                    if (notifyEventArgs.FirstChanged == 0 && notifyEventArgs.LastChanged == int.MaxValue) {
                        base.Invalidate();
                    } else {
                        this.InvalidateWindow(notifyEventArgs.FirstChanged, notifyEventArgs.LastChanged, (notifyEventArgs.State & NotifyState.Outline) != NotifyState.None);
                    }
                    if (notifyEventArgs.Update) {
                        this.scrolling.UpdateScroll(false);
                        this.UpdateCaret();
                    }
                    this.OnSourceStateChanged(notifyEventArgs.State, notifyEventArgs.FirstChanged, notifyEventArgs.LastChanged);
                }
            }
        }
        public virtual void OnStateChanged(object sender, NotifyState state) {
            if ((state & NotifyState.SelectedTextChanged) != NotifyState.None || (state & NotifyState.ScrollingOriginChanged) != NotifyState.None) {
                this.vertNavigate = false;
            }
            if ((state & NotifyState.ScrollingOptionsChanged) != NotifyState.None || (state & NotifyState.SelectionOptionsChanged) != NotifyState.None) {
                base.SetStyle(ControlStyles.ResizeRedraw, this.NeedResizeRedraw());
            }
            if ((state & NotifyState.PageOptionsChanged) != NotifyState.None) {
                this.OnTransparentChanged();
            }
            if ((state & NotifyState.SelectionChanged) != NotifyState.None) {
                this.UpdateStartSearchPos();
            }
        }
        private void InvalidateLine(int index) {
            if (index >= 0) {
                Point point = this.DisplayToScreen(0, index);
                int displayWidth = this.gutter.DisplayWidth;
                int right = this.ClientRect.Right;
                base.Invalidate(new Rectangle(displayWidth, point.Y - 1, right - displayWidth + 1, this.painter222.lineHeight + 2));
            }
        }
        private void UpdateSeparator() {
            if (this.lineSeparator.NeedHighlight()) {
                this.InvalidateLine(this.oldLine);
                this.oldLine = this.displayLines.PointToDisplayPoint(this.Position).Y;
                this.InvalidateLine(this.oldLine);
            }
        }
        private void ClearCurrentBlock() {
            if (this.currentBlockRange != null) {
                this.BeginUpdate();
                try {
                    this.InvalidateWindow(this.currentBlockRange.StartPoint.Y, this.currentBlockRange.EndPoint.Y, true);
                    this.currentBlockRange = null;
                } finally {
                    this.EndUpdate();
                }
            }
        }
        private void UpdateCurrentBlock() {
            if (!this.Focused && !this.highlightCurrentBlock) {
                this.ClearCurrentBlock();
            } else {
                Point position = this.Position;
                int num = this.scrolling.WindowOriginY + this.GetLinesInHeight(position.Y - this.ClientRect.Top);
                SyntaxParser syntaxParser = (SyntaxParser)this.Source.Lexer;
                Range range = (syntaxParser != null) ? syntaxParser.GetRangeAt(position) : null;
                if (this.currentBlockRange != null || range != null) {
                    if ((this.currentBlockRange == null && range != null) || (this.currentBlockRange != null && range == null) || !this.currentBlockRange.StartPoint.Equals(range.StartPoint) || !this.currentBlockRange.EndPoint.Equals(range.EndPoint)) {
                        try {
                            this.BeginUpdate();
                            if (this.currentBlockRange != null) {
                                this.ClearCurrentBlock();
                            }
                            this.currentBlockRange = range;
                            if (this.currentBlockRange != null) {
                                this.InvalidateWindow(this.currentBlockRange.StartPoint.Y, this.currentBlockRange.EndPoint.Y, true);
                            }
                        } finally {
                            this.EndUpdate();
                        }
                    }
                }
            }
        }

        private void MovePage(bool direction) {
            this.displayLines.DisableUpdate();
            try {
                Point position = this.scrolling.ScrollByPixels ? this.TextToScreen(this.Position) : this.displayLines.PointToDisplayPoint(this.Position);
                if (this.vertNavigate) {
                    position.X = this.vertNavigateX;
                }
                int x = position.X;
                if (!this.scrolling.ScrollByPixels) {
                    position = this.DisplayToScreen(position.X, position.Y);
                }
                int num = this.scrolling.ScrollByPixels ? this.ClientRect.Height : Math.Max(this.LinesInHeight - 1, 0);
                if (direction) {
                    num += this.scrolling.WindowOriginY;
                } else {
                    num = this.scrolling.WindowOriginY - num;
                }
                if (num < 0) {
                    this.scrolling.WindowOriginY = 0;
                    this.MoveToLine(0);
                } else {
                    this.scrolling.DisableUpdate();
                    try {
                        int windowOriginY = this.scrolling.WindowOriginY;
                        this.scrolling.WindowOriginY = num;
                        bool lineEnd = false;
                        position = this.ScreenToText(position.X, position.Y, ref lineEnd);
                        this.displayLines.LineEnd = lineEnd;
                        this.scrolling.WindowOriginY = windowOriginY;
                    } finally {
                        this.scrolling.EnableUpdate();
                    }
                    this.scrolling.WindowOriginY = num;
                    this.MoveTo(position);
                }
                this.vertNavigate = true;
                this.vertNavigateX = x;
            } finally {
                this.displayLines.EnableUpdate();
            }
            this.ClearSelection();
        }
        protected void ClearSelection() {
            if (this.selection.UpdateCount == 0 && !this.selection.IsEmpty && (this.selection.Options & SelectionOptions.PersistentBlocks) == SelectionOptions.None) {
                this.selection.Clear();
            }
        }
        public virtual void MoveCharLeft() {
            bool flag = false;
            Point point = this.displayLines.PointToDisplayPoint(this.Position);
            if (point.X == 0 && (NavigateOptions.UpAtLineBegin & this.NavigateOptions) != NavigateOptions.None) {
                point.X = this.displayLines[point.Y - 1].Length;
                point.Y--;
                this.displayLines.LineEnd = true;
                flag = true;
            } else {
                if (point.X > 0) {
                    point.X--;
                }
            }
            if (flag) {
                this.displayLines.DisableUpdate();
                this.Source.BeginUpdate(UpdateReason.Navigate);
                try {
                    this.Source.State |= NotifyState.PositionChanged;
                    this.MoveTo(this.displayLines.DisplayPointToPoint(point.X, point.Y, true, true, false));
                } finally {
                    this.Source.EndUpdate();
                    this.displayLines.EnableUpdate();
                }
            } else {
                this.MoveTo(this.displayLines.DisplayPointToPoint(point.X, point.Y, true, true, false));
            }
            this.ClearSelection();
        }
        public virtual void MoveCharRight() {
            bool flag = false;
            Point point = this.displayLines.PointToDisplayPoint(this.Position);
            if (point.X >= this.displayLines[point.Y].Length && (this.NavigateOptions & NavigateOptions.BeyondEol) == NavigateOptions.None) {
                if ((this.NavigateOptions & NavigateOptions.DownAtLineEnd) != NavigateOptions.None) {
                    if ((this.NavigateOptions & NavigateOptions.BeyondEof) != NavigateOptions.None || point.Y < this.displayLines.DisplayCount - 1) {
                        point.Y++;
                        point.X = 0;
                        this.displayLines.LineEnd = false;
                        flag = true;
                    }
                }
            } else {
                point.X++;
            }
            if (flag) {
                this.Source.BeginUpdate(UpdateReason.Navigate);
                try {
                    this.Source.State |= NotifyState.PositionChanged;
                    this.MoveTo(this.displayLines.DisplayPointToPoint(point.X, point.Y, false, false, true));
                } finally {
                    this.Source.EndUpdate();
                }
            } else {
                this.MoveTo(this.displayLines.DisplayPointToPoint(point.X, point.Y, false, false, true));
            }
            this.ClearSelection();
        }
        public virtual void MoveWordLeft() {
            Point point = this.displayLines.PointToDisplayPoint(this.Position);
            string text = this.displayLines[point.Y];
            if (point.X == 0) {
                if (point.Y > 0) {
                    point.Y--;
                    text = this.displayLines[point.Y];
                    point.X = text.Length;
                } else {
                    point = new Point(0, 0);
                }
            }
            int num = Math.Min(point.X, text.Length);
            if (num > 0) {
                while (num > 0 && this.displayLines.IsWhitespace(text, num - 1)) {
                    num--;
                }
                if (num > 0) {
                    bool flag = this.displayLines.IsDelimiter(text, num - 1);
                    bool flag2 = this.displayLines.IsWhitespace(text, num - 1);
                    while (num > 0 && this.displayLines.IsDelimiter(text, num - 1) == flag && this.displayLines.IsWhitespace(text, num - 1) == flag2) {
                        num--;
                    }
                }
                if (num == point.X) {
                    num++;
                }
            }
            this.MoveTo(this.displayLines.DisplayPointToPoint(num, point.Y, false, true, false));
        }
        public virtual void MoveWordRight() {
            Point position = this.displayLines.PointToDisplayPoint(this.Position);
            string text = this.displayLines[position.Y];
            int length = text.Length;
            if (position.X >= length) {
                if (position.Y + 1 < this.displayLines.DisplayCount) {
                    position.Y++;
                    text = this.displayLines[position.Y];
                    position.X = text.Length - text.TrimStart(new char[0]).Length;
                } else {
                    position.X = length;
                }
                this.MoveTo(this.displayLines.DisplayPointToPoint(position));
            } else {
                int num = position.X;
                bool flag = this.displayLines.IsDelimiter(text, num);
                bool flag2 = this.displayLines.IsWhitespace(text, num);
                while (num < length && this.displayLines.IsDelimiter(text, num) == flag && this.displayLines.IsWhitespace(text, num) == flag2) {
                    num++;
                }
                while (num < length && this.displayLines.IsWhitespace(text, num)) {
                    num++;
                }
                if (num == position.X) {
                    num++;
                }
                this.MoveTo(this.displayLines.DisplayPointToPoint(num, position.Y, false, false, true));
            }
        }
        public virtual void MoveLineUp() {
            this.displayLines.DisableUpdate();
            try {
                Point point = this.displayLines.PointToDisplayPoint(this.Position);
                if (point.Y > 0) {
                    point.Y--;
                }
                if (this.scrolling.ScrollByPixels) {
                    point.X = this.DisplayToScreen(point.X, point.Y).X;
                }
                if (this.vertNavigate) {
                    point.X = this.vertNavigateX;
                }
                int x = this.scrolling.ScrollByPixels ? this.ScreenToDisplayX(point.X, point.Y) : point.X;
                bool lineEnd = false;
                Point position = this.displayLines.DisplayPointToPoint(x, point.Y, ref lineEnd);
                this.displayLines.LineEnd = lineEnd;
                this.MoveTo(position);
                this.vertNavigate = true;
                this.vertNavigateX = point.X;
            } finally {
                this.displayLines.EnableUpdate();
            }
            this.ClearSelection();
        }
        public virtual void MoveLineDown() {
            this.displayLines.DisableUpdate();
            try {
                Point point = this.displayLines.PointToDisplayPoint(this.Position);
                if (this.scrolling.ScrollByPixels) {
                    point.X = this.DisplayToScreen(point.X, point.Y).X;
                }
                if (this.vertNavigate) {
                    point.X = this.vertNavigateX;
                }
                point.Y++;
                int x = this.scrolling.ScrollByPixels ? this.ScreenToDisplayX(point.X, point.Y) : point.X;
                bool lineEnd = false;
                Point position = this.displayLines.DisplayPointToPoint(x, point.Y, ref lineEnd);
                this.displayLines.LineEnd = lineEnd;
                this.MoveTo(position);
                this.vertNavigate = true;
                this.vertNavigateX = point.X;
            } finally {
                this.displayLines.EnableUpdate();
            }
            this.ClearSelection();
        }
        public virtual void MoveLineBegin() {
            Point position = this.displayLines.PointToDisplayPoint(this.Position);
            position.X = 0;
            this.MoveTo(this.displayLines.DisplayPointToPoint(position));
            this.ClearSelection();
        }
        public virtual void MoveLineEnd() {
            Point position = this.displayLines.PointToDisplayPoint(this.Position);
            position.X = this.displayLines[position.Y].Length;
            this.displayLines.DisableUpdate();
            try {
                this.displayLines.LineEnd = true;
                this.MoveTo(this.displayLines.DisplayPointToPoint(position));
            } finally {
                this.displayLines.EnableUpdate();
            }
            this.ClearSelection();
        }
        public virtual void MoveLineBeginCycled() {
            Point position = this.displayLines.PointToDisplayPoint(this.Position);
            string text = this.displayLines[position.Y];
            int num = text.Length - text.TrimStart(new char[0]).Length;
            position.X = ((position.X == num) ? 0 : num);
            this.MoveTo(this.displayLines.DisplayPointToPoint(position));
            this.ClearSelection();
        }
        public virtual void MoveLineEndCycled() {
            Point position = this.displayLines.PointToDisplayPoint(this.Position);
            string text = this.displayLines[position.Y];
            int length = text.TrimEnd(new char[0]).Length;
            position.X = ((position.X == length) ? text.Length : length);
            this.MoveTo(this.displayLines.DisplayPointToPoint(position));
            this.ClearSelection();
        }
        public virtual void MoveFileBegin() {
            this.MoveTo(0, 0);
            this.ClearSelection();
        }
        public virtual void MoveFileEnd() {
            if (this.Lines.Count == 0) {
                this.MoveTo(0, 0);
            } else {
                this.MoveTo(this.Lines.GetLength(this.Lines.Count - 1), this.Lines.Count - 1);
            }
            this.ClearSelection();
        }
        public virtual void MovePageUp() {
            this.MovePage(false);
        }
        public virtual void MovePageDown() {
            this.MovePage(true);
        }
        public virtual void MoveScreenTop() {
            this.displayLines.DisableUpdate();
            try {
                Point position = this.displayLines.PointToDisplayPoint(this.Position);
                int x = position.X;
                if (this.scrolling.ScrollByPixels) {
                    x = this.DisplayToScreen(position.X, position.Y).X;
                }
                if (this.vertNavigate) {
                    x = this.vertNavigateX;
                }
                Point point = this.scrolling.ScrollByPixels ? this.ScreenToDisplay(x, this.ClientRect.Top) : new Point(x, this.scrolling.WindowOriginY);
                bool lineEnd = false;
                position = this.displayLines.DisplayPointToPoint(point.X, point.Y, ref lineEnd);
                this.displayLines.LineEnd = lineEnd;
                this.MoveTo(position);
                this.vertNavigate = true;
                this.vertNavigateX = x;
            } finally {
                this.displayLines.EnableUpdate();
            }
            this.ClearSelection();
        }
        public virtual void MoveScreenBottom() {
            this.displayLines.DisableUpdate();
            try {
                Point position = this.displayLines.PointToDisplayPoint(this.Position);
                int x = position.X;
                if (this.scrolling.ScrollByPixels) {
                    x = this.DisplayToScreen(position.X, position.Y).X;
                }
                if (this.vertNavigate) {
                    x = this.vertNavigateX;
                }
                Point point = this.scrolling.ScrollByPixels ? this.ScreenToDisplay(x, this.ClientRect.Bottom - this.painter222.lineHeight) : new Point(x, this.scrolling.WindowOriginY + Math.Max(this.LinesInHeight - 1, 0));
                bool lineEnd = false;
                position = this.displayLines.DisplayPointToPoint(point.X, point.Y, ref lineEnd);
                this.displayLines.LineEnd = lineEnd;
                this.MoveTo(position);
                this.vertNavigate = true;
                this.vertNavigateX = x;
            } finally {
                this.displayLines.EnableUpdate();
            }
            this.ClearSelection();
        }
        public virtual void ScrollLineUp() {
            if (this.scrolling.ScrollByPixels) {
                this.scrolling.WindowOriginY -= this.painter222.lineHeight;
            } else {
                this.scrolling.WindowOriginY--;
            }
        }
        public virtual void ScrollLineDown() {
            if (this.scrolling.ScrollByPixels) {
                this.scrolling.WindowOriginY += this.painter222.lineHeight;
            } else {
                this.scrolling.WindowOriginY++;
            }
        }
        public virtual void MoveToOpenBrace() {
            Point position = this.Position;
            if (Array.IndexOf<char>(this.braces.ClosingBraces, this.Lines.GetCharAt(position)) >= 0) {
                if (this.braces.FindOpenBrace(ref position)) {
                    this.Position = position;
                }
            }
        }
        public virtual void MoveToCloseBrace() {
            Point position = this.Position;
            if (Array.IndexOf<char>(this.braces.OpenBraces, this.Lines.GetCharAt(this.Position)) >= 0) {
                position.X++;
                if (this.braces.FindClosingBrace(ref position)) {
                    this.Position = position;
                }
            }
        }
        public virtual void MoveToBrace() {
            Point position = this.Position;
            if (Array.IndexOf<char>(this.braces.OpenBraces, this.Lines.GetCharAt(position)) >= 0) {
                position.X++;
                if (this.braces.FindClosingBrace(ref position)) {
                    this.Position = position;
                }
            } else {
                if (Array.IndexOf<char>(this.braces.ClosingBraces, this.Lines.GetCharAt(position)) >= 0) {
                    if (this.braces.FindOpenBrace(ref position)) {
                        this.Position = position;
                    }
                } else {
                    if (position.X > 0 && Array.IndexOf<char>(this.braces.OpenBraces, this.Lines.GetCharAt(new Point(position.X - 1, position.Y))) >= 0) {
                        if (this.braces.FindClosingBrace(ref position)) {
                            this.Position = position;
                        }
                    } else {
                        if (position.X > 0 && Array.IndexOf<char>(this.braces.ClosingBraces, this.Lines.GetCharAt(new Point(position.X - 1, position.Y))) >= 0) {
                            position.X--;
                            if (this.braces.FindOpenBrace(ref position)) {
                                this.Position = position;
                            }
                        }
                    }
                }
            }
        }
        public virtual bool ProcessTab(Point position) {
            return this.SelectSnippet(position, true, (this.selection.Options & SelectionOptions.DisableCodeSnippetOnTab) == SelectionOptions.None);
        }
        public virtual bool ProcessShiftTab(Point position) {
            return this.SelectSnippet(position, false, false);
        }
        public virtual bool ProcessEnter() {
            bool result;
            if (this.InIncrementalSearch) {
                this.FinishIncrementalSearch();
                result = true;
            } else {
                Circus.CodeEditor.TextSource.TextSource textSource = this.Source;
                int num;
                if (textSource.CodeSnippets.FindSnippet(this.Position, false, out num)) {
                    CodeSnippetRange codeSnippetRange = null;
                    foreach (CodeSnippetRange current in textSource.CodeSnippets) {
                        if (current.ID == "$" + EditConsts.DefaultSnippetEndPattern + "$") {
                            codeSnippetRange = current;
                            break;
                        }
                    }
                    textSource.CurrentSnippet = codeSnippetRange;
                    if (codeSnippetRange != null) {
                        this.MoveTo(codeSnippetRange.StartPoint);
                        this.selection.SmartIndent();
                    }
                    textSource.UnhighlightCodeSnippets();
                    result = true;
                } else {
                    result = false;
                }
            }
            return result;
        }
        public virtual void Navigate(int deltaX, int deltaY) {
            this.Source.Navigate(deltaX, deltaY);
        }
        public virtual void MoveTo(int x, int y) {
            this.Source.MoveTo(x, y);
        }
        public virtual void MoveTo(Point position) {
            this.Source.MoveTo(position);
        }
        public virtual void MoveToChar(int x) {
            this.Source.MoveToChar(x);
        }
        public virtual void MoveToLine(int y) {
            this.Source.MoveToLine(y);
        }

        public virtual int StorePositionWithUndo(Point position) {
            return this.Source.StorePositionWithUndo(position);
        }
        public virtual void RestorePositionWithUndo(int index) {
            this.Source.RestorePositionWithUndo(index);
        }
   
        public virtual int StorePosition(Point position, bool endPos) {
            return this.Source.StorePosition(position, endPos);
        }

        public virtual Point RestorePosition(int index) {
            return this.Source.RestorePosition(index);
        }

        public virtual void SetNavigateOptions(NavigateOptions navigateOptions) {
            this.Source.SetNavigateOptions(navigateOptions);
        }
    
        public virtual int BeginUpdate() {
            return this.Source.BeginUpdate();
        }
        public virtual int EndUpdate() {
            return this.Source.EndUpdate();
        }
   
        public virtual bool UpdateWordWrap() {
            return this.displayLines.UpdateWordWrap();
        }
        public virtual bool UpdateWordWrap(int first, int last) {
            return this.displayLines.UpdateWordWrap(first, last);
        }
        public virtual int GetWrapMargin() {
            return this.displayLines.GetWrapMargin();
        }
   

    }
}
